use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use anyhow::{anyhow, Result};

#[derive(Debug, Clone)]
pub struct Metrics {
    data:Arc<Mutex<HashMap<String,i64>>>,
}

impl Metrics {
    pub fn new() -> Self {
        Metrics{
            data:Arc::new(Mutex::new(HashMap::new())),
        }
    }

    pub fn inc(&self, key:impl Into<String>) -> Result<()>{
        let mut  data = self.data.lock().map_err(
            |err| {
            anyhow!(err.to_string())
        })?;
        let mut counter = data.entry(key.into()).or_insert(0);
        *counter += 1;
        Ok(())
    }

    pub fn dec(&self, key:impl Into<String>) -> Result<()> {
        let mut  data = self.data.lock().map_err(
            |err| {
                anyhow!(err.to_string())
            })?;
        let mut counter = data.entry(key.into()).or_insert(0);
        *counter -=1;
        Ok(())
    }



    pub fn snapshot(&self) -> Result<HashMap<String,i64>> {
       Ok(self.data.lock().map_err(|e|anyhow!(e.to_string()))?.clone())
    }
}